<template>
  <div class="progress-operation">
    <div ref="progress" class="progress">
      <div v-if="isUnfold" ref="operation" class="timeline-operation">
        <!-- <div class="row tooltip">*控制工序显示状态，默认隐藏所有<span>关闭</span>状态工序</div> -->
        <!-- details -->
        <basic-pie
          class="pie"
          :pieData="pieData"
          :selected="filterOptions"
          @on-selected-change="onSelectedChange"
        />
      </div>
      <div class="timeline-wrapper" :style="`height: ${timelineHeight}px`">
        <ws-time-line
          :timeline-array="filter_activities"
          :current="current_key"
          :wrapperColor="renderWrapper"
          @on-dot-click="onDotClick"
          @onPanelClose="onPanelClose"
        />
      </div>
    </div>
    <div class="process">
      <transition name="component-fade" mode="out-in">
        <keep-alive>
          <component
            :is="current_component"
            :key="current_key"
            :meter="current_meter"
            :title="current_key"
            :status="current_key_status"
          />
        </keep-alive>
      </transition>
    </div>
  </div>
</template>

<script lang="ts">
import Vue from 'vue'
import { Component, Watch, Ref } from 'vue-property-decorator'
import { Route } from 'vue-router'
import { Getter } from 'vuex-class'
import { App } from '@/store/interface/app'
import { TimeLineSetting } from '@/interface/Basic'
import { default_wrapper_dark_color, default_wrapper_light_color } from '@/confirgurations/Basic'
import { Dictionary } from '@/interface/Basic'
import { GetProcedureList, ResetProcedure, CloseProcedure } from '@/api/procedure'
import { AxiosResponse } from 'axios'
// 组件
import { Message } from 'element-ui'
import WsTimeLine from '@/components/tool/ws-timeline.vue'
import BasicPie from '@/components/echarts/basic_pie.vue'
import AAG from '../procedure_module/AAG/product_init.vue'
import AAL from '../procedure_module/AAL/product_final.vue'
import AAP from '../procedure_module/AAP/thrid_party_test.vue'
import AAU from '../procedure_module/AAU/return_record.vue'
import AAT from '../procedure_module/AAT/none_standard.vue'
import AAE from '../procedure_module/AAE/zero_flow.vue'
import AAO from '../procedure_module/AAO/flow_verify.vue'
import AAK from '../procedure_module/AAK/air_tightness.vue'
import AAN from '../procedure_module/AAN/into_storage.vue'
import AAA from '../procedure_module/AAA/computer.vue'
import AAB from '../procedure_module/AAB/computer.vue'
import AAC from '../procedure_module/AAC/computer.vue'
import AAD from '../procedure_module/AAD/computer.vue'
import AAH from '../procedure_module/AAH/signal_debug.vue'
import AAM from '../procedure_module/AAM/quality_test.vue'
import { deepClone } from '@/utils/specificFunc'
Component.registerHooks(['beforeRouteEnter'])
@Component({
  components: {
    WsTimeLine,
    BasicPie,
    AAG,
    AAL,
    AAP,
    AAU,
    AAT,
    AAE,
    AAO,
    AAK,
    AAN,
    AAA,
    AAB,
    AAC,
    AAD,
    AAH,
    AAM
  }
})
class ProgressManage extends Vue {
  @Ref() progress!: HTMLElement
  @Ref() operation!: HTMLElement
  @Getter('theme') theme!: 'light' | 'dark'
  @Getter('name') username!: string
  @Getter('sidebar') sidebar!: App['sidebar']
  activities: TimeLineSetting[] = []
  pieData: {
    name: string
    value: number
  }[] = []
  timelineHeight: number = 0
  current_meter: string = ''
  current_key: string = ''
  current_key_status: string = ''
  current_component: string = ''
  isUnfold = true
  filterOptions: string[] = []
  filter_activities: TimeLineSetting[] = []
  get statusList() {
    if (this.activities.length === 0) return []
    const map: Dictionary<number> = {}
    this.activities.forEach(item => {
      if (!map[item.content.status]) map[item.content.status] = 1
      else map[item.content.status] = map[item.content.status] + 1
    })
    return Object.keys(map).map(status => {
      return {
        label: status,
        value: status,
        num: map[status]
      }
    })
  }
  @Watch('statusList')
  sl_handler(newVal: { label: string; value: string }[]) {
    const status = newVal.map(item => item.value)
    const idx = status.findIndex(item => item === '关闭')
    if (idx === -1) this.filterOptions = status
    else {
      status.splice(idx, 1)
      this.filterOptions = status
    }
  }
  @Watch('filterOptions')
  fo_handler(newVal: string) {
    this.filter_activities = this.activities.filter(item => newVal.includes(item.content.status))
    const ele = this.filter_activities.find(item => item.content.procname === this.current_key)
    const final_ele = ele ? ele : this.filter_activities[0]
    this.current_key = final_ele.content.procname
    this.current_key_status = final_ele.content.status
    this.current_component = final_ele.name
    // 生成 pieData
    this.pieData = this.statusList.map(li => {
      return {
        name: li.label,
        value: li.num
      }
    })
    this.computeTimelineHeight()
  }
  // 路由守卫
  beforeRouteEnter(to: Route, from: Route, next: (...args: any) => void) {
    const { meterid } = to.params
    GetProcedureList(meterid ? meterid : 'default')
      .then((res: AxiosResponse<{ ReturnData: TimeLineSetting[] }>) => {
        const { ReturnData } = res.data
        const disabled_procedure_num = ReturnData.filter(item => item.disabled).length
        if (disabled_procedure_num === ReturnData.length) {
          Message({
            message: '您没有任何工序的操作权限，请联系管理员授予',
            type: 'error'
          })
          next(from)
        } else {
          next()
        }
      })
      .catch(() => {
        next(from)
      })
  }
  // beforeRouteLeave(to: Route, from: Route, next: (...args: any) => void) {
  //   setTimeout(() => {
  //     this.$confirm('请确保数据全部保存或上传，避免数据丢失！！', '提示', {
  //       confirmButtonText: '确定',
  //       cancelButtonText: '取消',
  //       type: 'warning'
  //     })
  //       .then(() => {
  //         next()
  //       })
  //       .catch(() => {
  //         next(from)
  //       })
  //   }, 200)
  // }
  mounted() {
    const { meterid } = this.$route.params
    this.current_meter = meterid
    // if (this.sidebar.opened) this.$store.dispatch('app/toggleSideBar')
    this.initProcedureList()
    this.computeTimelineHeight()
    window.addEventListener('resize', this.computeTimelineHeight)
    this.$broadOn('onProcedureReset', (option: { Procname: string; Number: string }) => {
      this.resetCurrent(option)
    })
    this.$broadOn('onProcedureClose', (option: { Procname: string; Number: string }) => {
      this.closeCurrent(option)
    })
    this.$broadOn('onProcedureReport', () => {
      this.initProcedureList()
    })
  }
  beforeDestroy() {
    window.removeEventListener('resize', this.computeTimelineHeight)
  }
  initProcedureList() {
    const { meterid } = this.$route.params
    const { procname } = this.$route.query
    GetProcedureList(meterid).then((res: AxiosResponse<{ ReturnData: TimeLineSetting[] }>) => {
      const { ReturnData } = res.data
      this.activities = ReturnData
      const first_ele = ReturnData.find(item => item.content.procname === procname)
      if (first_ele) {
        this.current_key = first_ele.content.procname
        this.current_key_status = first_ele.content.status
        this.current_component = first_ele.name
      }
    })
  }
  computeTimelineHeight() {
    this.$nextTick(() => {
      const { height: parent_height } = this.progress.getBoundingClientRect()
      let sub_height = 0
      if (this.operation) {
        sub_height = this.operation.getBoundingClientRect().height
      }
      this.timelineHeight = parent_height - sub_height
    })
  }
  renderWrapper(status: string) {
    return this.theme === 'dark'
      ? {
          color: ['未完成', '关闭', ''].includes(status) ? '#555555' : '#FFFFFF',
          backgroundColor: default_wrapper_dark_color[status]
        }
      : {
          color: ['未完成', '关闭', ''].includes(status) ? '#555555' : '#FFFFFF',
          backgroundColor: default_wrapper_light_color[status]
        }
  }
  onDotClick(dot: TimeLineSetting) {
    if (dot.disabled) {
      Message({
        message: '您没有该工序的操作权限，请联系管理员授予',
        type: 'error'
      })
      return
    }
    this.$router.push({
      query: {
        procname: dot.content.procname
      }
    })
    this.current_component = dot.name
    this.current_key = dot.content.procname
    this.current_key_status = dot.content.status
  }
  onPanelClose(status: boolean) {
    this.isUnfold = status
    this.computeTimelineHeight()
  }
  onSelectedChange(selected: string[]) {
    if (selected.length === 0) {
      this.$message({
        type: 'warning',
        message: '当前展示工序数量不能为零'
      })
      this.filterOptions = deepClone(this.filterOptions)
      return
    }
    this.filterOptions = selected
    this.computeTimelineHeight()
  }
  onRemoveTag(tag: string) {
    if (this.filterOptions.length === 0) {
      Message({
        type: 'warning',
        message: '时间线节点不能为空'
      })
      this.filterOptions = [tag]
    }
  }
  resetCurrent(option: { Procname: string; Number: string }) {
    ResetProcedure({
      Operator: this.username,
      ...option
    }).then((res: AxiosResponse<{ Message: string }>) => {
      Message({
        type: 'success',
        message: res.data.Message
      })
      this.initProcedureList()
    })
  }
  closeCurrent(option: { Procname: string; Number: string }) {
    CloseProcedure({
      Operator: this.username,
      ...option
    }).then((res: AxiosResponse<{ Message: string }>) => {
      Message({
        type: 'success',
        message: res.data.Message
      })
      this.initProcedureList()
    })
  }
}
export default ProgressManage
</script>

<style lang="less" scoped>
@import '~@/styles/theme.less';
@import '~@/styles/layout.less';
.progress-operation {
  box-sizing: border-box;
  padding-top: 10px;
  height: calc(100vh - 50px);
  display: flex;
  align-items: flex-end;
  justify-content: flex-start;
  #color(background-color, --primary-bg-color);
  .progress {
    height: 100%;
    z-index: 1;
    #color(background-color, --module-bg-color);
    #shadow-color(4px, 4px, 12px, 0, --primary-shadow-color);
    .timeline-operation {
      min-width: 275px;
      border-bottom: solid 1px;
      #flex(column, center, flex-start);
      #color(border-bottom-color, --primary-border-color);
      .pie {
        width: 100%;
        height: 135px;
      }
    }
    .timeline-wrapper {
      height: calc(100% - 240px);
    }
  }
  .process {
    position: relative;
    flex: 1;
    height: 100%;
    overflow-y: auto;
    overflow-x: hidden;
    transition: all 0.2s ease;
    #color(background-color, --module-bg-color);
    .open {
      padding: 0 5px;
      .filter-content,
      .details-content {
        box-sizing: border-box;
        width: 100%;
        font-size: 12px;
        text-align: left;
        padding: 5px 0;
        margin-bottom: 5px;
        border-bottom: solid 1px;
        #color(border-bottom-color, --primary-border-color);
        #color(color, --primary-text-color);
        #flex(column, flex-start, space-between);
        .title {
          margin-bottom: 5px;
          #flex(row, center, flex-start);
          span {
            padding: 0;
          }
        }
      }
      .details-content {
        .content {
          span {
            width: unset;
            padding: 5px 0;
            margin-right: 15px;
          }
          flex-wrap: wrap;
          #flex(row, center, flex-start);
        }
        span {
          border-bottom: unset !important;
        }
      }
      .buttons-content {
        width: 100%;
        margin: 5px 0;
        #flex(row, center, space-between);
        span {
          width: 48%;
        }
        .el-popover__reference-wrapper {
          .el-button {
            width: 100%;
            i {
              margin-right: 5px;
              color: #ffffff;
              font-size: 12px;
            }
          }
        }
      }
    }
  }
}
// .proper-filter {
.iconfont {
  #color(color, --primary-text-color);
}
.el-popover__reference-wrapper {
  i {
    cursor: pointer;
  }
}
.component-fade-enter-active,
.component-fade-leave-active {
  transition: all 0.5s cubic-bezier(0.79, 0.14, 0.15, 0.86);
}
.component-fade-enter {
  opacity: 0.5;
  transform: translateX(-100%);
}
.component-fade-leave-to {
  opacity: 0.5;
  transform: translateX(100%);
}
</style>
